<?
//ob
ob_start();

//turn off for testing
//~ error_reporting(0);

//configuration
include "conf.php";

//includes
include "php/functions.php";
include "php/facebook.api.php";

//error-handling:
set_error_handler(myErrorHandler);

//init crpyto
$master_crypt=new Crypt_RC4();
$master_crypt->setKey(hexToString($_MISC['master-key']));
$crypt=new Crypt_RC4();

//connect2db
$_DB = new PDO("mysql:host={$_MYSQL['host']};dbname={$_MYSQL['db_name']}", $_MYSQL['db_user'], $_MYSQL['password'],array(PDO::ATTR_PERSISTENT => true));
$_DB->query("SET CHARACTER SET 'utf8'");

//start user-session
session_name($_MISC['cookie-name']);
session_set_cookie_params($_MISC['cookie-duration']); //70 days in seconds
session_start();
if(!$_SESSION['regdate_first']) $_SESSION['regdate_first']=date('Y-m-d H:i:s');

if(!usession_get('agent_survey')) {
	updateAndSetUserData(usession_get('email'),array('user_agent'=>$_SERVER['HTTP_USER_AGENT']));
	usession_set('agent_survey',true);
}

/* ACTIONS */
//load auth_modules
if($_GET['auth']) {
	if(is_file("php/auth.{$_GET['auth']}.php")) {
		require_once "php/auth.{$_GET['auth']}.php";
		authentificate();
		exit;
	}
	exit;
}

//facebook
require_once("php/auth.facebook.php");

//start song session
if($_GET['play'] == 'start') {
	if(!is_session_authentificated())
	exit('error: not authentificated'); 
	$song_hash = $master_crypt->decrypt_b64($_SERVER['HTTP_X_PLAYER_DATA']);
	$song=$_DB->prepare('SELECT * FROM `songs` WHERE `hash` = :hash');$song->execute(array('hash'=>$song_hash));
	if($song=$song->fetch()) {
		if(user_hasSongPlayRights($song)<1) exit('error: you are not allowed to play this song');
		$start_key=md5(generate_key()).md5(generate_key());
		$start_hash=md5(generate_key());
		$session_key=song_hash($song['mp3name'].rand(), $song['titile'].rand(), $song['length'].rand());
		$hash_counter=rand(10000000,999999999);
		//create song_session
		$query=$_DB->prepare('INSERT INTO `song_sessions` (email, song_id, hash_time, play_time, current_hash, scrobbel, hash_counter, current_key, session_key, transfered, user_agent) VALUES (:email, :song_id, :hash_time, :play_time, :current_hash, :scrobbel, :hash_counter, :current_key, :session_key, :transfered,:user_agent)');
		$query->execute(array(
			'email'=>usession_get('email') ,
			'song_id'=>$song['song_id'],
			'hash_time'=>time(),
			'play_time'=>date('Y-m-d H:i:s'),
			'transfered'=>0,
			'current_hash'=>$start_hash,
			'scrobbel'=>0,
			'user_agent'=>$_SERVER['HTTP_USER_AGENT'],
			'hash_counter'=>$hash_counter,
			'current_key'=>$start_key,
			'session_key'=> $session_key));
		//~ print_r($query->errorInfo());
		$message = json_encode(array('start_hash'=>$start_hash, 'start_key'=>$start_key, 'song_scrobbel'=>intval($song['length']*$_MISC['scrobbelAt']*1000),'session_key'=> $session_key,'hash_counter'=>$hash_counter,'hash_update_time'=>($_MISC['hash-validity-duration']/2)*1000));//,JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP);
		logi(intval($song['length']*$_MISC['scrobbelAt']*1000));
		echo $master_crypt->encrypt_b64($message);
	}
	exit;
}
if($_GET['play'] == 'stream') {
	$session_key = $master_crypt->decrypt_b64($_SERVER['HTTP_X_PLAYER_SESSION']);
	$songsession=$_DB->prepare('SELECT * FROM `song_sessions` WHERE `session_key` = :key AND `email` = :email');$songsession->execute(array('key'=>$session_key,'email'=>usession_get('email')));
	if($songsession=$songsession->fetch()) {
		$userInfo=get_userInfo();
		$crypt->setKey(hexToString($songsession['current_key']));
		$song=$_DB->prepare('SELECT * FROM `songs` WHERE `song_id` = :sid AND hash = :hash');$song->execute(array('sid'=>$songsession['song_id'], 'hash'=>$crypt->decrypt_b64($_SERVER['HTTP_X_PLAYER_DATA'])));
		if($song=$song->fetch()) {
			$interval=0.2; //every 0.2s, data is flushed
			$hash_interval=$_MISC['hash-validity-duration']; //every max s, the hash has to be renewed
			$filename="media/".$song['mp3name'];
			$filesize=filesize($filename);
			logi("Streaming {$song['mp3name']} to ".usession_get('email'));
			header("Content-Type: audio/x-mp3");
			header("Content-Length: " .(string)$filesize );
			header("Cache-Control: no-cache");
			$fp=fopen($filename, "rb");
			$firstpart=200*1024;//flush first 100Kb
			echo fread($fp, $firstpart); ob_flush(); 
			$step=intval((($filesize-$firstpart)/(intval($song['length'])*(1/$interval)))*1.3); //step for further flushes per 0.x seconds
			$email=usession_get('email');
			//close session to allow auth-procedure to access it
			session_write_close();
			//~ for($t=0;($t*$step)+$firstpart<$filesize;$t=$t+$interval) {
			while($chunk=fread($fp, $step)) {
				//~ print(fread($fp, $step)); ob_flush(); //flush stepkb
				print($chunk); ob_flush();
				usleep($interval*1000000); //sleep during intervall
				if(fmod($t, 2) == 0 ) { //check if hash is still valid every 2 seconds
					$songsession=$_DB->prepare('SELECT * FROM `song_sessions` WHERE `session_key` = :key AND `email` = :email');$songsession->execute(array('key'=>$session_key,'email'=>$email));
					$songsession=$songsession->fetch();
					if(intval($songsession['hash_time']) <= time()-$_MISC['hash-validity-duration']) {
						logi("Stream {$song['mp3name']} to ".usession_get('email')." is not valid anymore.");
						exit('error: stream not valid anymore');
					}
				}
			}
			logi("finished streaming {$song['mp3name']} to ".usession_get('email'));
			//set stream to finished (transfer)
			$query=$_DB->prepare('UPDATE `song_sessions` SET `transfered` = 1 WHERE `session_key` = :key AND `email` = :email');$query->execute(array('key'=>$session_key,'email'=>$email));
		}
	}
	exit;
}
if($_GET['play'] == 'auth') {
	$session_key = $master_crypt->decrypt_b64($_SERVER['HTTP_X_PLAYER_SESSION']);
	$songsession=$_DB->prepare('SELECT * FROM `song_sessions` WHERE `session_key` = :key AND `email` = :email');$songsession->execute(array('key'=>$session_key,'email'=>usession_get('email')));
	if($songsession=$songsession->fetch()) {
		if($songsession['transfered']==1) 
			exit('finished');
		if(intval($songsession['hash_time']) <= time()-$_MISC['hash-validity-duration'])
			exit("error: stream not valid anymore");
		//calc new keys&hashes $songsession[' ']
		//~ $new_hash_counter=intval(($songsession['hash_counter']+($songsession['hash_counter']*(($songsession['hash_counter']/($songsession['hash_counter']-($songsession['hash_counter']*0.01)))*($songsession['hash_counter']/($songsession['hash_counter']-($songsession['hash_counter']*0.01))))))/2);
		$new_hash_counter=intval($songsession['hash_counter']/2);
		$new_current_key=md5($songsession['hash_counter'].$songsession['current_key']).md5($new_hash_counter.md5($songsession['hash_counter'].$songsession['current_key']));
		$new_current_hash=md5(md5($songsession['current_hash'].$new_current_key).md5($new_hash_counter)).md5($new_hash_counter.$songsession['hash_counter'].$new_current_key);
		//~ echo  "nhc: $new_hash_counter\nnck: $new_current_key\nnh: $new_current_hash";
		//~ echo "\n\na: ",$new_hash_counter.$songsession['hash_counter'].$new_current_key,"\n";
		//now decrypt&check
		$crypt->setKey(hexToString($new_current_key));
		if($new_current_hash==$crypt->decrypt_b64($_SERVER['HTTP_X_PLAYER_DATA'])) {
			$query=$_DB->prepare('UPDATE `song_sessions` SET `hash_time` = :hash_time , `current_hash` = :current_hash , `hash_counter` = :hash_counter , `current_key` = :current_key WHERE `session_key` = :session_key AND `email` = :email');$query->execute(array(
				'session_key'=>$session_key,
				'email'=>usession_get('email'),
				'hash_time'=>time(),
				'current_hash'=>$new_current_hash,
				'hash_counter'=>$new_hash_counter,
				'current_key'=>$new_current_key));
			logi(var_export($query->errorInfo(),true));
			exit('success');
		} else exit("error:2\n");
		//~ } else exit("error:2\nnhc: $new_hash_counter\nnck: $new_current_key\nnch: $new_current_hash\n\ndecrypt: ".($crypt->decrypt_b64($_SERVER['HTTP_X_PLAYER_DATA'])));
	}
	else exit('error:1');
	exit;
}
if($_GET['play'] == 'scrobbel') {
	$session_key = $master_crypt->decrypt_b64($_SERVER['HTTP_X_PLAYER_SESSION']);
	$songsession=$_DB->prepare('SELECT * FROM `song_sessions` WHERE `session_key` = :key AND `email` = :email');$songsession->execute(array('key'=>$session_key,'email'=>usession_get('email')));
	if($songsession=$songsession->fetch()) {
		$query=$_DB->prepare('UPDATE `song_sessions` SET `scrobbel` =1 WHERE `session_key` = :session_key AND `email` = :email');$query->execute(array(
				'session_key'=>$session_key,
				'email'=>usession_get('email')));
	}
}

/*AJAX-API*/
if($_GET['js'] and $_POST['param']) $_js_param=json_decode($_POST['param'],true);

if($_GET['js']=='get_songs') {
	$userInfo=get_userInfo();
	foreach($_DB->query('SELECT * FROM `songs` ORDER BY `treshold` ASC')->fetchAll() as $song) {
		$songlist[]=array('title'=>$song['title'], 'hash'=>$song['hash'], 'length'=>$song['length'],'hasRights'=>user_hasSongPlayRights($song,$userInfo));
	}
	$task=array("todo"=>"updateTrackList","param"=>$songlist);
	echo  json_encode($task, JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP);
	exit;
}
if($_GET['js']=='prepareSong') {
	$song = get_songFromHash($_js_param['hash']);
	switch(user_hasSongPlayRights($song)) {
		case 1:
			$g=array("booklet","livepics");
			$num=rand(0,count($g)-1);
			$url='js/slideshow/getimages/'.$g[$num];
			$task = array(
					array('todo'=>'playSong','param'=>array('hash'=>$_js_param['hash'])),
					array('todo'=>'showSlideshow','param'=>array('url'=>$url,'object'=>'cover-slideshow')),
					array('todo'=>'slideto','param'=>array('slideid'=>$num+1))
				);
			break;
		case 0:
			$task = array('todo'=>'showBox','param'=>array('url'=>'/box/pleaseauth')); break;
		case -1:
			$task = array('todo'=>'showBox','param'=>array('url'=>'/box/spreadtheword')); break;
	}
	echo  json_encode($task, JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP);
	exit;
}
if($_GET['js']=='slideshow') {
	echo json_encode(glob("images/slideshow/{$_GET['getimages']}/*.jpg"));;
	exit;
}
if($_GET['js']=='theunknownnotreproducablebaderrororccured_sadbuttrue') {
	$_DB->prepare("INSERT INTO `DONT PANIC`(`time`,`user_agent`,`email`) VALUES(:time,:user_agent,:email)")->execute(array("time"=>date('Y-m-d H:i:s'),"user_agent"=>$_SERVER['HTTP_USER_AGENT'], "email"=>usession_get("email")));
	exit;
}
if($_GET['js']=='installcount') {
	$installs=number_of_user_installs();
	$task=array('todo'=>'updateInstallCount','param'=>array('installs'=>$installs,'songs'=>number_of_songs_available($installs),'left'=>next_level($installs)-$installs,'songname'=>next_song($installs)));
	echo  json_encode($task, JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP);
	exit;
}
if($_GET['box']) {
	if(is_file("templates/box/{$_GET['box']}.php")) {
		include "templates/box/{$_GET['box']}.php";
		exit;
	}
	exit;
};



/*MAIN*/
//check authentification
//~ if(!is_session_authentificated()){
	//~ if(!usession_get('auth_mode')) {
		//~ $_AUTH_MODE = get_auth_mode();
		//~ usession_set('auth_mode', $_AUTH_MODE);
	//~ }
	//~ header('Location: /auth/'.usession_get('auth_mode'));
	//~ exit;
//~ }

//show site



include "templates/header.php";

//APC TEST
/*
if(!apc_exists('testkey')) {
	$var="Hello World!";
	apc_add('testkey', $var);
	echo 'saved testkey in apc-cache';
}
$text=apc_fetch('testkey');
echo "$text<br>";
*/

/*
echo "You are authentificated as ", usession_get('email'),'<br>';
echo "avaible songs:<br>";
*/
?>
<script type="text/javascript">
window.addEvent('domready', function() {
	<?if($_GET["action"]) {
		?>
		try{s_process("<?=$_GET["action"]?>");}catch(e){};
		<?
	}?>
	//amazon links
	$$(".amazon-preorder").each(function(el){el.addEvent("click", function(){window.open('http://goo.gl/3H0Fm','_newtab');})});

	//share
	$$(".section .share").each(function(el){el.addEvent("click",showBox.pass('box/spreadtheword'))});
	
	//slideshow
	//~ $$('.stop-slideshow').each(function(el){
		//~ el.addEvent("click",function() {
			//~ slideshow(null,$('cover-slideshow')); //destroys the slideshow
		//~ });
	//~ });
	//~ $$("[class^=start-slideshow-]").each(function(el) { 
		//~ el.addEvent('click', slideshow.pass(['js/slideshow/getimages/'+el.get('class').split('-')[2],$('cover-slideshow')]));
	//~ });
	
	if(Browser.Plugins.Flash.version<10 || !Browser.Plugins.Flash ) {
		$$('.error-message.no-flash').setStyles({'height':'auto','visibility':'visible','padding':'7px'});
	}
	
	coverbuttons_positions=[49,	115, 193]; //middle positions
	coverbuttons_actions=[{todo:'showSlideshow',param:{object:$('cover-slideshow'),url:null}},{todo:'showSlideshow',param:{object:$('cover-slideshow'),url:'js/slideshow/getimages/booklet'}},{todo:'showSlideshow',param:{object:$('cover-slideshow'),url:'js/slideshow/getimages/livepics'}},]
	coverbuttons_offset=40; //image_offset at  each side [<--offset---pos---offset-->]
	coverbuttons_current=0;
	
	$$(".cover-slider").set('morph',{'transition': 'bounce:out'});
	$$(".image-area").addEvent("mousemove",function(e){$$(".cover-slider").setStyle("left",e.client.x-coverbuttons_offset)});
	$$(".image-area").addEvent("mouseleave",function(e){$$(".cover-slider").morph({"left":coverbuttons_positions[coverbuttons_current]-coverbuttons_offset});})
	$$(".image-area").addEvent("click",function(e){
		coverbuttons_positions.each(function(curr,i,pos) {
			var lower=(pos[i-1]?pos[i-1]:0)+coverbuttons_offset;
			var upper=(pos[i+1]?pos[i+1]:9999999999)+coverbuttons_offset;
			if(e.client.x >= lower && e.client.x < upper) {
				coverbuttons_current=i;
				//fire animation
				$$(".image-area").fireEvent("mouseleave");
				//processactions:
				s_process(coverbuttons_actions[coverbuttons_current]);
			}
		});
	});
	
	
	<?
	if(!is_session_authentificated() AND !$_GET['notshowloginbox']) {
	?>
	bodyclick=function(e){
		e.stop();
        document.body.unmask();
        document.body.set("mask",{'class':'mask'});
		document.body.removeEvent('click',bodyclick);
		showBox('box/pleaseauth');
	}
	setbodyclick=function() {
		document.body.set("mask",{'class':'mask-almost-invisible'});
		document.body.mask()
		document.body.addEvent('click',bodyclick);
	}
	setbodyclick();
	<?
	} //end
	?>	
});

window.fbAsyncInit = function() {
        FB.init({
          appId   : '<?=$_FB->getAppId(); ?>',
          session : <?=json_encode($_FB->getSession());?>, // don't refetch the session when PHP already has it
          status  : true, // check login status
          cookie  : true, // enable cookies to allow the server to access the session
          xfbml   : true // parse XFBML
        });
      };

</script>


<div class="container">
	<noscript><div class="error-message">You have to enable Javascript in order to use this app!</div></noscript>
	<div class="error-message no-flash"><b>Error:</b> You need the newest version of flashplayer to use this app! <a target="_new" href="http://adobe.com/go/getflashplayer">Click here</a> to get it!</div>
	<div class="error-message no-browser"><b>Sad but True:</b>Sorry, something went wrong and this really should not have happened. Try to hit ctrl + F5 (strg + f5 on a German keyboard)<br>If this does not work a new browser might help <a target="_new" href="http://mozilla.org/firefox">Click here</a> to get one!</div>

	<div class="head">
		<!-- <div class="head-logo">--><div class="like"><script type="text/javascript">if(!Browser.ie6 && !Browser.ie7){document.writeln('<fb:like href="http://www.facebook.com/inlegend" layout="button_count" show_faces="false" width="80" font="">');}</script></div><!-- </div>-->
		<div><h1>Listen to the entire <a href="http://goo.gl/3H0Fm" title="Order at Amazon" target="_blank">Ballads 'n' Bullets</a> record by In Legend </h1></div>
	</div>
	<div class="section">
		<div class="fb-section-header"><div class="amazon-preorder"></div><strong>Select a song from <a href="http://goo.gl/3H0Fm" target="_blank">Ballads 'n' bullets</a></strong></div>
		<br>
		<div class="image-area" style="position: relative; overflow: hidden;cursor:pointer;">
			<div class="slideshow" id="cover-slideshow"></div>
			<div style="position: absolute; bottom: 0px; width: 100%; height: 31px; background: url('images/cover_subanimation.png') no-repeat scroll 0pt 0pt transparent; left: 11px;" class="cover-slider"></div>
			<div style="position: absolute; bottom: 0px; width: 100%; background: url('images/cover_subsections.png') repeat scroll 0% 0% transparent; height: 31px;" class="cover-buttons"></div>
		</div>
		<div class="track-list"></div>
		<div class="ad-buttons">
			<!-- <a href="http://www.inlegend.de/media/releases/ballads-n-bullets/" title="Read the lyrics @ inlegend.de" target="_blank">Lyrics</a> -->
			<a href="#" class="amazon-preorder"  title="Preorder Ballads 'n' Bullets by In Legend @ Amazon">Order Ballads n Bullets</a> 
			<a href="http://www.inlegend.de/shop" title="In Legend shirts & merchandise" target="_blank">Buy In Legend T-Shirts / Girlie Shirts</a> 
		</div>
	</div>
	<div class="section">
		<h1><strong>If you like our music why don't you <a href="#share" class="share">tell your friends</a></strong>?</h1>
		<div class="spacer-10"></div>
		<? /*
		<div class="fb-section-header"><div class="amazon-preorder"></div><a href="#share" class="share"><strong>You want the entire Album?</strong></a></div>
		<div class="sound-barometer">
			<div class="barometer">
				<div class="overlay">
					<div class="word-counter">
						<span class="installs">0</span> users installed the app already.<br> 
						<span class="left"><?=next_level();?></span> installs left for  <span class="songname">0</span>!
					</div>
				</div>
			</div>
		</div>
		*/?>
	</div>
	<div class="section share_bar">
		<script type="text/javascript">if(!Browser.ie6 && !Browser.ie7){document.writeln(' <div class="like"><fb:like href="http://www.facebook.com/inlegend" layout="button_count" show_faces="false" width="80" font=""></div>');}</script>
		<a href="http://twitter.com/share" class="twitter-share-button" data-text="listen to the entire @inlegendband album ballads n bullets on their #facebook #app http://goo.gl/Jkx4Y \m/ RT" data-count="horizontal">Tweet about it</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
		<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fapps.facebook.com%2Fballadsnbullets&amp;layout=button_count&amp;show_faces=false&amp;width=250&amp;action=recommend&amp;font&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:250px; height:21px;" allowTransparency="true"></iframe>
		<br><br>
		<input type="text" onclick="this.focus();this.select();" value="<iframe src='http://goo.gl/WUK8i' width='530' height='800' name='Ballads N Bullets Facebook App'>
			  	<p>Your Browser can't display iframes. go to: <a href='http://fbapp.rene-pickhardt.de'>this page</a> in order to listen</p>
				</iframe>" readonly>
		</input>&nbsp;<strong>COPY</strong> (ctrl + c) to <strong>EMBED</strong> the app to your website / blog<br><br>
	</div>
	<? /*
	<div class="section">
		<div class="fb-section-header">Comments</div>
			<div id="fb-root"></div><script src="http://connect.facebook.net/en_US/all.js#appId=182231535125653&amp;xfbml=1"></script><fb:comments href="http://apps.facebook.com/balladsnbullets/" num_posts="15" width="500"></fb:comments>
		</div>
	</div> */?>
	<div class="section">
		<div class="fb-section-header">Facebook app created by:</div>
		<div class="author-list">
			<a href="http://coderscave.net" target="_blank">Yann Leretaille</a>, Robert Naumann (<a href="http://nowman.org/portfolio/video/"  target="_blank">Music Video Production</a>) &amp;<br>
			<a href="http://www.rene-pickhardt.de"  target="_blank">Rene Pickhardt</a> (<a href="http://www.rene-pickhardt.de/cat/online-music-marketing/" title="read Rene Pickhardts blog category about online music marketing" target="_blank">online music marketing</a>,
				<a href="http://www.rene-pickhardt.de/bandpage-seo-the-perfect-band-website-part1/" title="search engine optimization for your band's website" target="_blank">music band website <acronym title="search engine optimization" target="_blank">seo</acronym></a> &
				<a href="http://www.metalcon.de" title="Metal community for bands and fans" target="_blank">metal community</a>)
		</div>
	</div>
</div>
<script>new Element('script',{src: 'http://static.ak.fbcdn.net/connect.php/js/FB.Share'}).inject(document.body)</script>
<div id="flashcontainer"></div>
<?
include "templates/footer.php";
?>
